var PCHBVZ = {

    callbackCount : 0,
    process : [],
    datasets : [],
    stacked : false,

    makeFunc : function(n) {
        return function(json) {
            PCHBVZ.callbackCount++;
            PCHBVZ.datasets[n] = json;
            if (PCHBVZ.callbackCount >= PCHBVZ.process.length) {
                postProcess(PCHBVZ.datasets);
            }
        }
    },

    date2JS : function(timestamp) {
        if (typeof(timestamp) != "function") {
            var ts_parts = timestamp.split('T');
            var d_parts = ts_parts[0].split('-');
            var t_parts = ts_parts[1].split(':');
            var d = new Date(parseInt(d_parts[0], 10), parseInt(d_parts[1], 10) - 1, parseInt(d_parts[2], 10), parseInt(t_parts[0], 10), parseInt(t_parts[1], 10), parseInt(t_parts[2], 10));
            return d;
        }
    },

    insertVisualization : function(feed, datastream, n) {
        var headID = document.getElementsByTagName('head')[0];
        var newScript = document.createElement('script');
        newScript.type = 'text/javascript';
        // newScript.src = 'http://apps.pachube.com/history/archive_json.php?f=6001&d=0&callback=process';
        newScript.src = 'http://apps.pachube.com/history/archive_json.php?f='+feed+'&d='+datastream+'&callback=PCHBVZ.process['+n+']';
        headID.appendChild(newScript);
    },

    processViz : function(datasets) {
        var idx = [];
        var times = [];
        var zeros = [];
        var t0 = datasets[0]['time'];
        var start = this.date2JS(t0[t0.length-1]).getTime();
        var finish = this.date2JS(t0[0]).getTime();
        var data = new google.visualization.DataTable();
        data.addColumn('datetime', 'Date');
        for (var ds in datasets) {
            var ts = datasets[ds]['time'];
            for (var t in ts) {
                ts[t] = this.date2JS(ts[t]).getTime();
            }
            start = (ts[ts.length-1] < start) ? ts[ts.length-1] : start;
            finish = (ts[0] > finish) ? ts[0] : finish;
            idx.push(0);
            times.push(ts);
            zeros.push(0.0);
            data.addColumn('number', 'Datastream value '+ds);
        }

        var json = data.toJSON();
        for (var dt=finish; dt>start; dt-=900000) {
            var gotData = false;
            for (var i in idx) {
                if (times[i][idx[i]] <= dt) {
                    gotData = true;
                }
            }
            if (gotData) {
                var row = zeros.slice(0); // http://my.opera.com/GreyWyvern/blog/show.dml/1725165
                var thisrow = data.addRow();
                data.setValue(thisrow, 0, new Date(dt));
                for (var i in idx) {
                    if (times[i][idx[i]] <= dt) {
                        var val = parseFloat(datasets[i]['value'][idx[i]]);
                        row[i] = val;
                        idx[i]++;
                    }
                }
                for (var i in idx) {
                    ii = parseInt(i);
                    if (this.stacked) {
                        if (ii > 0) {
                            row[ii] += row[ii-1];
                        }
                    }
                    data.setValue(thisrow, ii+1, row[ii]);
                }
            }
        }
        return data;
    },

    createViz : function(feeddatastreams, stacked, width, height, color, min, max) {
        this.stacked = stacked;
        for (var i=0; i<feeddatastreams.length; i++) {
            this.process[i] = this.makeFunc(i);
        }
        var maxmin = "";
        var feed = feeddatastreams[0][0];
        var datastream = feeddatastreams[0][1];
        if (arguments.length == 6) maxmin = "scaleType:'allmaximized',min:" + min + ",max:" + max + ",";
        if (typeof(google) == 'undefined') {
            document.write("<script type=\"text/javascript\" src=\"http://www.google.com/jsapi\"></script>");
        }
        document.write("<script type=\"text/javascript\"> google.load(\'visualization\',\'1\',{packages:[\'annotatedtimeline\']});");
        document.write("function drawVisualization(){ ");
        for (var i=0; i<feeddatastreams.length; i++) {
            feed = feeddatastreams[i][0];
            datastream = feeddatastreams[i][1];
            document.write("PCHBVZ.insertVisualization(", feed, ",", datastream, ",", i, "); ");
        }
        document.write(" } ");
        document.write("function postProcess(datasets){ var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('visualization')); chart.draw(PCHBVZ.processViz(datasets), {displayAnnotations:true,thickness:1,", maxmin, "displayExactValues:true,fill:20,colors:['#", color, "']}); } google.setOnLoadCallback(drawVisualization); </script><div id=\"visualization\" style=\"width:", width, "px; height:", height, "px; font-size:small;\"></div><div style=\"width:", width, "px; background-color:#fff; margin:3px; padding-top:6px;\"><a href=\"http://www.pachube.com/feeds/", feed, "\" target=\"_new\"><img src=\"http://apps.pachube.com/google_viz/powered_by_pachube.png\" alt=\"powered by pachube!\" border=\"0\" style=\"\"></a></div>");
    }

}

